function [ecode, msg] = checkrng(arg_names,actual,low,up,lowname,upname,leq,ueq,fun)
%CHECKRNG Tests input arguments against upper and lower bounds.
%   CHECKRNG verifies that a given argument meets the specified boundary
%   conditions. This function is called from functions in the Financial Toolbox
%   to perform input argument range checking.
%
%   [ECODE, ERRMSG] = CHECKRNG(ARG_NAMES, ACTUAL, LOW, UP, LOWNAME, UPNAME, ...
%                              LEQ, UEQ, FUN)
%
%   Inputs:
%   ARG_NAMES - String matrix or cell array of function input argument names.
%
%      ACTUAL - Scalar value(s) of the ARG_NAMES input argument(s).
%
%         LOW - Scalar lower boundary value.
%
%          UP - Scalar upper boundary value.
%
%     LOWNAME - String matrix or cell array of the lower boundary variables.
%
%      UPNAME - String matrix or cell array of the upper boundary variables.
%
%         LEQ - Setting LEQ to 'e' constrains the input argument value to be
%               greater than or equal to LOW. LEQ = 'l' constrains the input
%               argument to be greater than LOW.
%
%         UEQ - Setting UEQ to 'e' constrains the input argument to be less
%               than or equal to UP. UEQ = 'l' constrains the input argument
%               to be less than UP.
%
%         FUN - Name of the function that calls CHECKRNG.
%
%   Outputs:
%       ECODE - Specifies if any boundary conditions are violated.
%               1 - Yes
%               0 - No
%
%      ERRMSG - Displays an error message as an output (instead of to the command
%               window) if boundary conditions are not met.
%
%   For example:
%      To check whether the input argument named rate falls between 0 and
%      infinity.
%
%      [ecode, errMsg] = checkrng('rate', -0.1, 0, inf, '0', 'inf', 'e', 'l', mfilename)
%
%      ecode =
%           1
%
%      errMsg =
%      rate must be >= 0.
%
%   See also CHECKSIZ, CHECKTYP.

%   Copyright 1995-2006 The MathWorks, Inc.
%   $Revision: 1.8.2.5 $   $Date: 2008/03/28 15:22:17 $

[rinp, cinp] = size(arg_names); %#ok

ecode = 0;  % Initialize ECODE
msg = '';   % No errors

for i = 1:rinp
    if leq(i) == 'e'
        if any(actual(:, i) < low(:, i))
            ecode = 1;
            disp(char(32))
            msgHeader = sprintf('??? Error using ==> %s\n', fun);

            if ischar(arg_names) && ischar(lowname)
                % char char
                msg = sprintf('%s must be >= %s.', arg_names(i, :), lowname(i, :));

            elseif iscell(arg_names) && ischar(lowname)
                % cell char
                msg = sprintf('%s must be >= %s.', arg_names{i}, lowname(i, :));

            elseif iscell(arg_names) && iscell(lowname)
                % Cell cell
                msg = sprintf('%s must be >= %s.', arg_names{i}, lowname{i});

            else
                % char cell
                msg = sprintf('%s must be >= %s.', arg_names(i, :), lowname{i});

            end

            if nargout <= 1
                fprintf([msgHeader, msg, '\n\n'])
            end
        end

    else
        if any(actual(:, i) <= low(:, i))
            ecode = 1;
            disp(char(32))
            msgHeader = sprintf('??? Error using ==> %s\n', fun);

            if ischar(arg_names) && ischar(lowname)
                % char char
                msg = sprintf('%s must be > %s.', arg_names(i, :), lowname(i, :));

            elseif iscell(arg_names) && ischar(lowname)
                % cell char
                msg = sprintf('%s must be > %s.', arg_names{i}, lowname(i, :));

            elseif iscell(arg_names) && iscell(lowname)
                % cell cell
                msg = sprintf('%s must be > %s.', arg_names{i}, lowname{i});

            else
                % char cell
                msg = sprintf('%s must be > %s.', arg_names(i, :), lowname{i});

            end

            if nargout <= 1
                fprintf([msgHeader, msg, '\n\n'])
            end
        end
    end

    if ueq(i) == 'e'
        if any(actual(:, i) > up(:, i))
            ecode = 1;
            disp(char(32))
            msgHeader = sprintf('??? Error using ==> %s\n', fun);

            if ischar(arg_names) && ischar(upname)
                % char char
                msg = sprintf('%s must be <= %s.', arg_names(i, :), upname(i, :));

            elseif iscell(arg_names) && ischar(upname)
                % cell char
                msg = sprintf('%s must be <= %s.', arg_names{i}, upname(i, :));

            elseif iscell(arg_names) && iscell(upname)
                % Cell cell
                msg = sprintf('%s must be <= %s.', arg_names{i}, upname{i});

            else
                % char cell
                msg = sprintf('%s must be <= %s.', arg_names(i, :), upname{i});

            end

            if nargout <= 1
                fprintf([msgHeader, msg, '\n\n'])
            end
        end

    else
        if any(actual(:, i) >= up(:, i))
            ecode = 1;
            disp(char(32))
            msgHeader = sprintf('??? Error using ==> %s\n', fun);

            if ischar(arg_names) && ischar(upname)
                % char char
                msg = sprintf('%s must be < %s.', arg_names(i, :), upname(i, :));

            elseif iscell(arg_names) && ischar(upname)
                % Cell char
                msg = sprintf('%s must be < %s.', arg_names{i}, upname(i, :));

            elseif iscell(arg_names) && iscell(upname)
                % cell cell
                msg = sprintf('%s must be < %s.', arg_names{i}, upname{i});

            else
                % char cell
                msg = sprintf('%s must be < %s.', arg_names(i, :), upname{i});

            end

            if nargout <= 1
                fprintf([msgHeader, msg, '\n\n'])
            end
        end
    end
end


% [EOF]
